package org.gemini.linear.multivariate;

import java.util.List;
import java.util.ArrayList;

import Jama.Matrix;

import org.gemini.model.TradeFundFlowDirection;
import org.gemini.service.TradeFundFlowDirectionService;
import org.gemini.service.impl.TradeFundFlowDirectionServiceImpl;

public class MultivariateLinearRegression {
	private int argumentNumber=5;
	private TradeFundFlowDirectionService tradeFundFlowDirectionService;
	private List<MultivariateDataPoint> multivariateDataPointList;
	private List<TradeFundFlowDirection> tradeFundFlowDirectionList;
	
	public MultivariateLinearRegression() {
	}
	
	public MultivariateLinearRegression(
			List<MultivariateDataPoint> multivariateDataPointList) {
		this.multivariateDataPointList = multivariateDataPointList;
	}
	
	public void add(MultivariateDataPoint mdp){
		multivariateDataPointList=new ArrayList<MultivariateDataPoint>();
		multivariateDataPointList.add(mdp);
	}
	
	public void obtainMultivariateLinearRegressionModel(){
		tradeFundFlowDirectionService=new TradeFundFlowDirectionServiceImpl();
		tradeFundFlowDirectionList = tradeFundFlowDirectionService.readTradeFundFlowDirectionList();
		
		double[][] arrayArgument=new double[tradeFundFlowDirectionList.size()][argumentNumber+1];
		double[] arrayDependent=new double[tradeFundFlowDirectionList.size()];
		for(int i=0;i<tradeFundFlowDirectionList.size();i++){
			arrayArgument[i]=new double[]{1,
					tradeFundFlowDirectionList.get(i).getLargeSheetNetInflowAmount(),
					tradeFundFlowDirectionList.get(i).getMainForceNetInflowAmount(),
					tradeFundFlowDirectionList.get(i).getMiddleSheetNetInflowAmount(),
					tradeFundFlowDirectionList.get(i).getSmallSheetNetInflowAmount(),
					tradeFundFlowDirectionList.get(i).getSuperLargeSheetNetInflowAmount()};
			arrayDependent[i]=tradeFundFlowDirectionList.get(i).getUpDownRange();
		}
		
      	Matrix matrixArgument = new Matrix(arrayArgument);
      	Matrix matrixArgumentTranspose=matrixArgument.transpose();
      	Matrix matrixDependent = new Matrix(arrayDependent,tradeFundFlowDirectionList.size());
      	Matrix result=matrixArgumentTranspose.times(matrixArgument).inverse().times(matrixArgumentTranspose).times(matrixDependent);
      	result.print(result.getRowDimension(),2);
		for(int i=0;i<result.getRowDimension();i++){
			System.out.println("constant"+i+"  :  "+result.get(i,0));
		}
	}
	
	public List<MultivariateDataPoint> getMdpList() {
		return multivariateDataPointList;
	}
	public void setMdpList(List<MultivariateDataPoint> multivariateDataPointList) {
		this.multivariateDataPointList = multivariateDataPointList;
	}
}
